#include"util.hpp"
#include"protocol.hpp"

using std::cerr;
using std::endl;
using std::string;
using std::cin;
using std::getline;
using std::cout;

volatile bool quit=false;
void Usage( string proc)
{
    cerr<<"Usage::\n\t"<<proc<<"serverIp serverPort"<<endl;
    cerr<<"example::\n\t"<<proc<<"127.0.0.1 8080"<<endl;
}

int main(int argc,char* argv[])
{
    if(argc!=3)
    {
        Usage(argv[0]);
        exit(USE_ERR);
    }
    string serverIp=argv[1];
    uint16_t serverPort=atoi(argv[2]);

    int sockFd=socket(AF_INET,SOCK_STREAM,0);
    if(sockFd<0)
    {
        logMessage(FATAL,"socket() failed::%s %d",strerror(errno),sockFd);
        exit(SOCKET_ERR);
    }
    logMessage(DEBUG,"socket() success::%d",sockFd);

    struct sockaddr_in server;
    memset(&server,0,sizeof(server));
    server.sin_port=serverPort;
    server.sin_family=AF_INET;
    inet_aton(serverIp.c_str(),&server.sin_addr);
    if(connect(sockFd,(const sockaddr*)&server,sizeof(server))==-1)
    {
        logMessage(FATAL,"connect() failed::%s: %d",strerror(errno),sockFd);
        exit(CONNECT_ERR);
    }
    logMessage(DEBUG,"connect() success.");

    string message;
    while(!quit)
    {
        message.clear();
        cout<<"Please enter";
        getline(cin,message);
        if(strcasecmp(message.c_str(),"quit")==0)
        {
            quit=true;
            continue;
        }
        request req;
        if(!makeRequest(message,&req))
        {
            continue;
        }
        string package;
        req.serialize(&package);
        package=encode(package,package.size());

    ssize_t sw=write(sockFd,package.c_str(),package.size());
    if(sw>0)
    {
        char buff[BUFFER_SIZE];
        ssize_t sr=read(sockFd,buff,sizeof(buff)-1);
        if(sr>0)
        {
            message[sr]='\0';
        }
        std::string echoPackage=buff;
        response resp;
        uint32_t packageLen=0;
        echoPackage=decode(echoPackage,&packageLen);
        if(packageLen)
        {
            resp.deserialize(echoPackage);
            printf("[exitcode :%d] %d\n",resp.get_exitCode(),resp.get_result());
        }
    }
    else if(sw<0)
    {
        logMessage(FATAL,"Client write() failed: %d : %s",sockFd,strerror(errno));
        break;
    }
    }
    close(sockFd);
    return 0;
}
